package com.umeox.moto.watch.fitness.ui

import android.app.KeyguardManager
import android.content.Intent
import android.os.*
import android.view.View
import android.widget.ImageView
import android.widget.TextView
import androidx.lifecycle.ViewModelProvider
import com.umeox.moto.common.executor.ThreadExecutor
import com.umeox.moto.common.log.Logger
import com.umeox.moto.common.utils.DateUtils
import com.umeox.moto.watch.fitness.R
import com.umeox.moto.watch.fitness.adapter.ChallengeAdapter
import com.umeox.moto.watch.fitness.db.AppDatabase
import com.umeox.moto.watch.fitness.db.model.ChallengeRecord
import com.umeox.moto.watch.fitness.db.model.TodayChallenge
import com.umeox.moto.watch.fitness.event.ChallengeEvent
import com.umeox.moto.watch.fitness.ui.dialog.ChallengeResultDialog
import com.umeox.moto.watch.fitness.viewmodel.TimerViewModel
import com.umeox.moto.watch.themes.app.ThemeAppCompatActivity
import com.umeox.moto.watch.themes.widget.ProgressView
import com.umeox.watch.moto.dataservice.proxy.PullApiClientProxy
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
import java.util.*

class ChallengeActivity : ThemeAppCompatActivity(), View.OnClickListener {

    private val MSG_FINISH: Int = 0x10


    private lateinit var mTimeProgressView: ProgressView
    private lateinit var mChallengeLevelTv: TextView

    private lateinit var mChallengeLevelDescTv: TextView
    private lateinit var mCurrentActiveTimeTv: TextView
    private lateinit var mRewardsTv: TextView


    private lateinit var mEndConfirmRl: View
    private lateinit var mStartIv: ImageView
    private lateinit var mStopIv: ImageView


    private var mCurrentChallenge: TodayChallenge? = null

    private lateinit var mTimerViewModel: TimerViewModel


    private lateinit var mCurrentChallengeRecord: ChallengeRecord

    private var challengeResultDialog: ChallengeResultDialog? = null

    private var mTotalTime: Int = 0
    private var mCurrentChallengeIsFinished: Boolean = false

    private lateinit var vibrator: Vibrator

    private var wakeLock: PowerManager.WakeLock? = null
    private var kl: KeyguardManager.KeyguardLock? = null


    private val mHandler: Handler = Handler { msg ->
        if (msg.what == MSG_FINISH) {
            challengeResultDialog?.dismiss()
            //finish()
        }
        false
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        Logger.e("==================onCreate======================")
        mCurrentChallenge = intent.getParcelableExtra("challenge_data")

        if (mCurrentChallenge == null) {
            finish()
        }
        setContentView(R.layout.activity_challenge)

        mTimerViewModel = ViewModelProvider(this)[TimerViewModel::class.java]
        mCurrentChallengeRecord = ChallengeRecord()
        EventBus.getDefault().register(this)
        initView()
        registerViewModelObserver()
        initData()

    }

    private fun registerViewModelObserver() {

        mStopIv.setOnClickListener(this)
        findViewById<View>(R.id.iv_challenge_cancel).setOnClickListener(this)
        findViewById<View>(R.id.iv_challenge_confirm).setOnClickListener(this)
        mStartIv.setOnClickListener(this)


        mTimerViewModel.mElapsedTimeLiveData.observe(this) {
            mTotalTime = it.toInt()
            Logger.e("mTotalTime->$mTotalTime")
            if (it >= 3600) {
                mCurrentActiveTimeTv.text = String.format(
                    Locale.getDefault(), "%d:%02d:%02d", it / 3600, it % 3600 / 60,
                    it % 60
                )
            } else {
                mCurrentActiveTimeTv.text = String.format(
                    Locale.getDefault(), "%02d:%02d", it % 3600 / 60,
                    it % 60
                )
            }

            if ((it % 3) == 0L) {
                if (mTimeProgressView.progress < 1.0f) {
                    mTimeProgressView.progress = it / (mCurrentChallenge!!.duration * 60F)
                }
            }
        }
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onChallengeEvent(challengeEvent: ChallengeEvent) {
        wakeUpAndUnlock()
        vibrator = getSystemService(
            VIBRATOR_SERVICE
        ) as Vibrator
        vibrator.vibrate(500)
        Logger.e("Congratulations!,Challenge success")
        mCurrentChallengeIsFinished = true
        mTotalTime = challengeEvent.challengeTime.toInt()
        mCurrentChallenge?.challengeTimesLevel = mChallengeLevelDescTv.text.toString()
        mCurrentChallengeRecord.sportType = mCurrentChallenge?.sportType!!
        mCurrentChallengeRecord.endTime = System.currentTimeMillis()
        mCurrentChallengeRecord.totalTime = mTotalTime
        mCurrentChallengeRecord.todayMillis = DateUtils.getTodayMillis()
        mCurrentChallengeRecord.rewardValue =
            if (mCurrentChallengeIsFinished) mCurrentChallenge?.rewardValue!! else 0
        Logger.e("$mCurrentChallengeRecord")
        val id =
            AppDatabase.get().challengeRecordDao().save(mCurrentChallengeRecord)
        mCurrentChallengeRecord._id = id.toInt()

        mTimerViewModel.pause()

        uploadChallengeRecord(mCurrentChallengeRecord, false)
        val challengeResultDialog =
            ChallengeResultDialog(
                this@ChallengeActivity,
                mCurrentChallenge!!,
                true
            )
        challengeResultDialog.show()
        challengeResultDialog.setOnDismissListener {
            finish()
        }


    }

    override fun onDestroy() {
        super.onDestroy()
        Logger.e("==================onDestroy======================")
        releaseLock()
        EventBus.getDefault().unregister(this)
    }

    override fun onNewIntent(intent: Intent?) {
        Logger.e("==================onNewIntent======================")
        super.onNewIntent(intent)
        setIntent(intent)
        stopCurrentChallenge()
        mCurrentChallenge = intent?.getParcelableExtra("challenge_data")
        if (mCurrentChallenge == null) {
            finish()
        }
        initData()
    }

    private fun stopCurrentChallenge() {
        mTimerViewModel.end()
    }

    private fun initView() {

        mTimeProgressView = findViewById(R.id.time_progress)
        mChallengeLevelTv = findViewById(R.id.tv_challenge_daily)

        mChallengeLevelDescTv = findViewById(R.id.tv_challenge_desc)
        mCurrentActiveTimeTv = findViewById(R.id.tv_challenge_time)
        mRewardsTv = findViewById(R.id.tv_rewards)

        mStartIv = findViewById(R.id.iv_start)
        mStopIv = findViewById(R.id.iv_stop)
        mEndConfirmRl = findViewById(R.id.confirm_end_rl)
    }

    private fun initData() {
        setChallengeIvAndDesc(mCurrentChallenge)
        mRewardsTv.text =
            String.format(Locale.getDefault(), "+ %d", mCurrentChallenge?.rewardValue)
        mTimeProgressView.progress = 0F

        mCurrentChallengeRecord.startTime = System.currentTimeMillis()
        mTimerViewModel.start(mCurrentChallenge?.duration?.times(60)?.toLong()!!)

        mStartIv.isSelected = true
    }

    private fun setChallengeIvAndDesc(challengeBean: TodayChallenge?) {
        var resId = R.drawable.ic_walking
        var challengeLevelStr = resources.getString(R.string.easy_challenge_str)
        var challengeDescStr = resources.getString(R.string.walk_for_str)
        when (challengeBean?.sportType) {
            ChallengeAdapter.TYPE_WALK -> {
                resId = R.drawable.ic_walking
                challengeLevelStr = resources.getString(R.string.easy_challenge_str)
                challengeDescStr = resources.getString(R.string.walk_for_str)
            }
            ChallengeAdapter.TYPE_RUN -> {
                resId = R.drawable.ic_running
                challengeLevelStr = resources.getString(R.string.medium_challenge_str)
                challengeDescStr = resources.getString(R.string.run_for_str)
            }
            ChallengeAdapter.TYPE_SWIM -> {
                resId = R.drawable.ic_swimming
                challengeLevelStr = resources.getString(R.string.medium_challenge_str)
                challengeDescStr = resources.getString(R.string.swim_for_str)
            }
            ChallengeAdapter.TYPE_CYCLE -> {
                resId = R.drawable.ic_riding
                challengeLevelStr = resources.getString(R.string.medium_challenge_str)
                challengeDescStr = resources.getString(R.string.cycle_for_str)
            }
            ChallengeAdapter.TYPE_FOOTBALL -> {

                challengeLevelStr = resources.getString(R.string.hard_challenge_str)
                challengeDescStr = resources.getString(R.string.football_for_str)
            }
            ChallengeAdapter.TYPE_GYM -> {

                challengeLevelStr = resources.getString(R.string.hard_challenge_str)
                challengeDescStr = resources.getString(R.string.gym_for_str)
            }
            ChallengeAdapter.TYPE_JUMPROPE -> {

                challengeLevelStr = resources.getString(R.string.hard_challenge_str)
                challengeDescStr = resources.getString(R.string.jump_rope_for_str)
            }
            ChallengeAdapter.TYPE_YOGA -> {

                challengeLevelStr = resources.getString(R.string.hard_challenge_str)
                challengeDescStr = resources.getString(R.string.yoga_rope_for_str)
            }
        }

        mChallengeLevelTv.text = challengeLevelStr

        mChallengeLevelDescTv.text =
            String.format(Locale.getDefault(), challengeDescStr, challengeBean?.duration)
    }

    override fun onBackPressed() {

        mEndConfirmRl.visibility =
            if (mEndConfirmRl.visibility == View.VISIBLE) View.GONE else View.VISIBLE

    }


    private fun uploadChallengeRecord(
        mCurrentChallengeRecord: ChallengeRecord,
        needFinish: Boolean
    ) {
        val result = PullApiClientProxy.fetchBinder().uploadChallengeRecord(
            mCurrentChallenge?.id!!.toInt(),
            mCurrentChallengeRecord.sportType,
            DateUtils.formatDateTime(mCurrentChallengeRecord.startTime, "yyyyMMdd'T'HHmmssZ"),
            DateUtils.formatDateTime(mCurrentChallengeRecord.endTime, "yyyyMMdd'T'HHmmssZ"),
            mCurrentChallengeRecord.totalTime,
            mCurrentChallengeRecord.rewardValue
        )

        if (result) {
            mCurrentChallengeRecord.isUpload = true
            AppDatabase.get().challengeRecordDao().update(mCurrentChallengeRecord)
        }

        if (needFinish) {
            finish()
        }
    }


    private fun wakeUpAndUnlock() {
        if (kl == null) {
            val km = getSystemService(KEYGUARD_SERVICE) as KeyguardManager
            kl = km.newKeyguardLock("unLock")
        }
        //解锁
        kl?.disableKeyguard()
        if (wakeLock == null) {
            val pm = getSystemService(POWER_SERVICE) as PowerManager
            wakeLock = pm.newWakeLock(
                PowerManager.ACQUIRE_CAUSES_WAKEUP or PowerManager.FULL_WAKE_LOCK,
                javaClass.simpleName
            )
        }
        // 点亮亮屏
        wakeLock?.acquire()
    }

    private fun releaseLock() {
        if (wakeLock != null) {
            try {
                wakeLock?.release()
            } catch (th: Throwable) {
                Logger.e("Releasing wakelock failed:$th")
            }
        } else {
            Logger.e("Wakelock reference is null")
        }
    }

    override fun onClick(v: View?) {
        when (v?.id) {
            R.id.iv_start -> {
                mStartIv.isSelected = !mStartIv.isSelected
                if (mStartIv.isSelected) mTimerViewModel.start(
                    mCurrentChallenge?.duration?.times(60)?.toLong()!!
                ) else mTimerViewModel.pause()

            }
            R.id.iv_stop -> {
                mEndConfirmRl.visibility = View.VISIBLE
            }
            R.id.iv_challenge_cancel -> {
                mEndConfirmRl.visibility = View.GONE
            }
            R.id.iv_challenge_confirm -> {
                mEndConfirmRl.visibility = View.GONE
                if (!mStartIv.isSelected) {
                    mStartIv.isSelected = false
                    mTimerViewModel.pause()

                }

                mCurrentChallenge?.challengeTimesLevel = mChallengeLevelDescTv.text.toString()
                challengeResultDialog =
                    ChallengeResultDialog(
                        this@ChallengeActivity,
                        mCurrentChallenge!!,
                        mTotalTime >= mCurrentChallenge?.duration?.times(60)!!,

                        )
                challengeResultDialog?.setOnDismissListener {
                    Logger.e("=======OnDismissListener=======")
                    mHandler.removeMessages(MSG_FINISH)
                    finish()
                }
                challengeResultDialog?.show()

                //结束挑战
                mCurrentChallengeRecord.sportType = mCurrentChallenge?.sportType!!
                mCurrentChallengeRecord.rewardValue = mCurrentChallenge?.rewardValue!!
                mCurrentChallengeRecord.todayMillis = DateUtils.getTodayMillis()
                mCurrentChallengeRecord.endTime = System.currentTimeMillis()
                mCurrentChallengeRecord.totalTime = mTotalTime
                mCurrentChallengeRecord.rewardValue =
                    if (mCurrentChallengeIsFinished) mCurrentChallenge?.rewardValue!! else 0
                Logger.e("$mCurrentChallengeRecord")
                val id = AppDatabase.get().challengeRecordDao().save(mCurrentChallengeRecord)
                mCurrentChallengeRecord._id = id.toInt()
                ThreadExecutor.getInstance().io().execute {
                    uploadChallengeRecord(mCurrentChallengeRecord, false)
                }
                mHandler.sendEmptyMessageDelayed(MSG_FINISH, 5000)

            }
        }
    }

}